#include "my_header.h"

//数据库头文件
#include <mysql/mysql.h>
//连接错误检查宏
#define MYSQL_CONNECT_CHECK(cond, db, msg) \
    do { \
        if (cond) { \
            printf("%s Error: %s\n", msg, mysql_error(db)); \
            mysql_close(db); \
            return -1; \
        } \
    } while (0)

//查询错误检查宏
#define MYSQL_QUERY_CHECK(cond, db, msg) \
    do { \
        if (cond) { \
            printf("%s Error: %s\n", msg, mysql_error(db)); \
            return; \
        } \
    } while (0)

//定义两个结构体
//需要二次生成的结构体，从绝对路径里获取的参数
typedef struct pathinfo_s{
    char parentName[256];  //不是要填进去的项目，是一个检索项
    char parentPath[1024];  //需要一个父目录的绝对路径
    char fileName[256];  //从path里获取
} PathInfo;


typedef struct {
    char path[1024];  //新增需要的参数
    PathInfo *pathinfo;  //进一步生成
    int fileId;    //新增时自动生成
    int parentId;           //通过parentName检索，新增是要插入
    char userName[51];  //初始化就需要的参数
    int fileType;       //初始化默认，新增需要的参数
    char hashValue[1024];  // 如果为空，传 NULL
    int isDeleted;   //新增时默认
    int refCount;    //新增时默认
} VfsRecord;


//PathInfo 相关函数，二次生成各种切割出路径
//1.获取父目录的单一路径名
void getParentPath(const char *filepath, char *parentpath);


//2.从完整的路径中过去filename和parentname
//返回0则为成功，返回-1，则为路径错误
int prasePathName(const char *filepath, char *filename, char *parentname);


//3.PathInfo的初始化
PathInfo *InitPathInfo(const char *filepath);


//4.配套的关闭函数
void freePathInfo(PathInfo *p);

//涉及VfsRecord相关的函数
//5.初始化VfsRecord结构体，包含路径名，用户名，默认属性，和嵌套的Pathinfo
VfsRecord *initVfsRecord(const char *filepath, const char *username);


//6.配套清理函数
void freeVfsRecord(VfsRecord *p);


//这里是数据库操作相关函数，可复用
//7.查询父目录id，找不到则返回-1
int queryParentId(MYSQL *db, VfsRecord *p);


//8.插入语句的核心逻辑
int insertFile(MYSQL *db, VfsRecord *p);


//9.更新父目录的引用计数+1
//如果父目录的id不为0，即不为根目录，则对上一级目录的引用计数+1
int updateParentRef(MYSQL *db, VfsRecord *p);

//10.组合排列的插入语句
//创建文件的业务逻辑，包含父目录查找、插入、引用计数更新
int createFile(MYSQL *db, VfsRecord *rec, int filetype, const char *hashvalue);

//对单个文件的删除语句进行处理
//删除的逻辑是把当前的文件isdelete改为1，且父目录的refcount-1
//11.将isDelete改为1
int updateDetele(MYSQL *db, VfsRecord *p);

//12.更新父目录的引用计数
//有一个必然性逻辑，就是只要当前这个文件对应的VfsRecord节点是存在的，那就说明父目录的引用计数必然是大于1的
int deleteParentRef(MYSQL *db, VfsRecord *p);

//13.查询当前VfsRecord节点的refCount的函数
int queryRefCount(MYSQL *db, VfsRecord *p);


//14.查询当前节点的fileId的函数
int queryFileId(MYSQL *db, VfsRecord *p);

//15.递归删除语句
//如果当前要删除的这个节点引用计数大于1，先递归删除其所有子节点，最后再删除其本体
int deleteRecord(MYSQL *db, VfsRecord *p);

//16.查询并打印语句
void queryPrint(MYSQL *db, const char *sql);